package pl.iddqd.tester;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintStream;

import javax.microedition.amms.control.camera.CameraControl;
import javax.microedition.amms.control.camera.FlashControl;
import javax.microedition.lcdui.Canvas;
import javax.microedition.lcdui.Command;
import javax.microedition.lcdui.CommandListener;
import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Displayable;
import javax.microedition.lcdui.Form;
import javax.microedition.lcdui.Image;
import javax.microedition.media.Manager;
import javax.microedition.media.MediaException;
import javax.microedition.media.Player;
import javax.microedition.media.PlayerListener;
import javax.microedition.media.control.VideoControl;
import javax.microedition.media.control.VolumeControl;
import javax.microedition.midlet.MIDlet;
import javax.microedition.midlet.MIDletStateChangeException;

import pl.iddqd.tester.image.Color;
import pl.iddqd.tester.image.ColorImage;

public class ColorTester extends MIDlet implements CommandListener {
	private Display display;

	private Form form;

	private Command exit, back, capture, camera;

	private Player player;

	private Player mPlayer;

	private FlashControl flash;

	private CameraControl cameraControl;

	private VideoControl videoControl;

	private VolumeControl vc;

	private Speaker sp;

	private Video video;

	

	public ColorTester() {
		exit = new Command("Exit", Command.EXIT, 0);
		camera = new Command("Camera", Command.SCREEN, 0);
		back = new Command("Back", Command.BACK, 0);
		capture = new Command("Capture", Command.SCREEN, 0);

		form = new Form("Capture Video");
		form.addCommand(camera);
		form.setCommandListener(this);

	}

	protected void destroyApp(boolean arg0) throws MIDletStateChangeException {
		display = Display.getDisplay(this);
		display.setCurrent(form);
	}

	protected void pauseApp() {
		// TODO Auto-generated method stub

	}

	protected void startApp() throws MIDletStateChangeException {
		display = Display.getDisplay(this);
		display.setCurrent(form);
	}

	public void showCamera() {
		try {
			player = Manager.createPlayer("capture://video");
			player.realize();

			videoControl = (VideoControl) player.getControl("VideoControl");

			Canvas canvas = new VideoCanvas(this, videoControl);
			canvas.addCommand(back);
			canvas.addCommand(capture);
			canvas.setCommandListener(this);
			display.setCurrent(canvas);
			player.start();

			cameraControl = (CameraControl) player
					.getControl("javax.microedition.amms.control.camera.CameraControl");
			try {
				cameraControl.setExposureMode("night");
			} catch (IllegalArgumentException e) {
				form.append(e.getMessage());
			}

			try {
				flash = (FlashControl) player
						.getControl("javax.microedition.amms.control.camera.FlashControl");
				//flash.setMode(FlashControl.FORCE_WITH_REDEYEREDUCE);
			} catch (Exception e) {
				form.append(e.getMessage());
			}

		} catch (IOException ioe) {
			ioe.printStackTrace();
		} catch (MediaException me) {
			me.printStackTrace();
		}
	}

	class Speaker extends Thread implements PlayerListener {
		String[] ttsTexts;

		int i = 0;

		int counter;

		InputStream is;

		public Speaker(String[] ttsTexts, int counter) {
			this.ttsTexts = ttsTexts;
			this.counter = counter;

		}

		public synchronized void play() {
			clean();
			String text = ttsTexts[i];
			is = getClass().getResourceAsStream("/tts/pl/" + text + ".mp3");
			//DEBUG
			form.append("Gram text: "+ text +"\n");
			try {
				mPlayer = Manager.createPlayer(is, "audio/mpeg");

				mPlayer.addPlayerListener(this);
				mPlayer.realize();

				vc = (VolumeControl) mPlayer.getControl("VolumeControl");
				if (vc != null) {
					vc.setLevel(100);
				}
				Thread.sleep(500);
				mPlayer.prefetch();
				mPlayer.start();				
			} catch (MediaException e) {
				form.append(e.toString());
			} catch (IOException e) {
				form.append(e.toString());
			} catch (InterruptedException e) {				
				form.append(e.toString());
			} catch (Exception e) {
				form.append(e.toString());
			}
		}

		public void playerUpdate(Player player, String event, Object eventData) {
			if (event.equals(PlayerListener.END_OF_MEDIA)) {
				if (i < counter) {
					i++;
					play();
					//DEBUG
					form.append("Gram dzwiek: "+ String.valueOf(i) +"\n");
				} else {
					mPlayer.deallocate();
					mPlayer.close();
					clean();

				}
			}
		}

		public void clean() {
			if (mPlayer != null) {
				mPlayer = null;
			}
			if (vc != null) {
				vc = null;
			}

			if (is != null) {
				is = null;
			}

		}

		public void run() {
			play();
		}
	};

	class Video extends Thread {
		ColorTester midlet;

		public Video(ColorTester midlet) {
			this.midlet = midlet;
		}

		public void run() {
			captureVideo();

		}

		public void captureVideo() {
			int width, height;
			try {

				byte[] raw = videoControl.getSnapshot(null);
				int[] hcHistogram = new int[20];

				Image image = Image.createImage(raw, 0, raw.length);
				raw = null;

				form.append(image);
				display.setCurrent(form);
				player.close();
				player = null;
				videoControl = null;
				width = image.getWidth() / 2;
				height = image.getHeight() / 2;
				ColorImage cIm = new ColorImage(image);
				cIm.computeColorModels();
				//TODO:
				form.append("Przeliczyl \n");				
				hcHistogram = cIm.getHcHistogram();
				//TODO
				form.append("Dlugosc histogramu "+ hcHistogram.length);
				
				String[] ttsText = new String[100];

				int n = 0;
				for (int i = 1; i < hcHistogram.length; i++) {
					int p = (int) (hcHistogram[i] / (float) (width * height) * 100);
					if (p > 5) {
						form.append(Color.humanColors[i] + " : "
								+ String.valueOf(p) + "\n");
						ttsText[n] = Color.humanColors[i];
						ttsText[n + 1] = String.valueOf(p);
						ttsText[n + 2] = "procent";
						n += 3;
					}
				}

				sp = new Speaker(ttsText, n);
				sp.start();

			} catch (MediaException me) {
				me.printStackTrace();
			} catch (Exception e) {
				form.append(e.toString());
			}
			
		}
	};

	public void commandAction(Command c, Displayable s) {
		try {
			if (c == exit) {
				destroyApp(true);
				notifyDestroyed();
			} else if (c == camera) {
				showCamera();
			} else if (c == back)
				display.setCurrent(form);
			else if (c == capture) {
				video = new Video(this);
				video.start();
			}
		} catch (MIDletStateChangeException e) {

		}
	}
}
